home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / C_TUTR24.ARJ / LESSON10 < prev    next >
Text File  |  1986-03-21  |  14KB  |  354 lines

  1. .NT
  2.  A NOTE ABOUT THE LESSONS in C 
  3. .b4-24R5C4
  4. These were written while the author was ~Ilearning~N  the language and since
  5. .R6C4
  6. they  are  ~Ifree~N ( to  copy  and/or  distribute ) there  is  a money-back
  7. .R7C4
  8. guarantee on the accuracy of each and every statement in the lessons (!)
  9. .R9C4
  10. The  ~Idisplay~N  program was written ( in C ) in order to provide a vehicle
  11. .R10C4
  12. for displaying the lessons.
  13. .R12C5
  14. .B
  15. P.J.Ponzo
  16. .B
  17. Dept. of Applied Math
  18. .B
  19. Univ. of Waterloo
  20. .B
  21. Ontario N2L 3G1
  22. .K16,32
  23. PonzoTUTOR
  24. .WNT
  25.     the C PREPROCESSOR   
  26. .R4C1
  27. ~b~IBEGIN                                                  ~N   ~b~Imain()   {          ~N 
  28. ~b~I  DECLARE_AN_INTEGER x;                                ~N   ~b~I  int x;            ~N 
  29. ~b~I  LET x=0;                                             ~N   ~b~I  x=0;              ~N 
  30. ~b~I  AS_LONG_AS ( x IS_LESS_THAN 5 )  DO                  ~N   ~b~I  while (x<5) {     ~N 
  31. ~b~I  LET x INCREASE_BY 1;                                 ~N   ~b~I  x+=1;             ~N
  32. ~b~I  PRINT_x;                                             ~N   ~b~I  printf("%d",x);   ~N 
  33. ~b~I  THEN_STOP                                            ~N   ~b~I  }                 ~N 
  34. ~b~IEND                                                    ~N   ~b~I}                   ~N 
  35.     Wouldn't it be nice if we could write the Left-Hand program (above) and
  36.     have it (magically) turn itself into the Right-Hand program?
  37. .WK16,60
  38. GOOD LUCK!
  39. .W
  40.     This would require the following ~Idefinitions~N:
  41. define  ~b~IBEGIN~N               to mean    ~b~Imain() {~N
  42. define  ~b~IDECLARE_AN_INTEGER~N  to mean    ~b~Iint~N
  43. define  ~b~ILET~N                 to mean     (nothing!)
  44. define  ~b~IAS_LONG_AS~N          to mean    ~b~Iwhile~N
  45. define  ~b~IIS_LESS_THAN~N        to mean    ~b~I<~N
  46. define  ~b~IDO~N                  to mean    ~b~I{~N
  47. define  ~b~IINCREASE_BY~N         to mean    ~b~I+=~N
  48. define  ~b~IPRINT_x~N             to mean    ~b~Iprintf("%d",x)~N
  49. define  ~b~ITHEN_STOP~N           to mean    ~b~I}~N
  50. define  ~b~IEND~N                 to mean    ~b~I}~N
  51. .WN
  52.  
  53.     One fascinating aspect of the ~IC~N language is its ability to perform
  54.     replacements of ~b~IBEGIN~N  by ~b~Imain()  {~N, and ~b~ILET~N by
  55.     nothing (a "null string") and ~b~IEND~N by ~b~I}~N, etc. etc.
  56.  
  57.     Before the C-compiler goes to work on your program, a ~IC-preprocessor~N
  58.     will make the appropriate replacements ... and (MAGIC!) the compiler gets
  59.     a normal, standard, C program to compile.
  60.  
  61.     To tell the preprocessor that you have redefined certain C-phrases, you
  62.     need only ~Ibegin~N your program with these ~I#definitions~N.
  63. .WK16,32
  64. begpardon?
  65. .WNT
  66.     #define THIS and THAT   
  67. .R4C1
  68. ~b~I#define  BEGIN                 main() {       ~N
  69. ~b~I#define  DECLARE_AN_INTEGER    int            ~N
  70. ~b~I#define  LET                                  ~N
  71. ~b~I#define  AS_LONG_AS            while          ~N
  72. ~b~I#define  IS_LESS_THAN          <              ~N
  73. ~b~I#define  INCREASE_BY           +=             ~N
  74. ~b~I#define  PRINT_x               printf("%d",x) ~N
  75. ~b~I#define  THEN_STOP             }              ~N
  76. ~b~I#define  END                   }              ~N
  77. ~b~I                                              ~N
  78. ~b~IBEGIN                                                  ~N  
  79. ~b~I  DECLARE_AN_INTEGER x;                                ~N  
  80. ~b~I  LET x=0;                                             ~N  
  81. ~b~I  AS_LONG_AS ( x IS_LESS_THAN 5 ) DO                   ~N  
  82. ~b~I  PRINT_x;                                             ~N  
  83. ~b~I  THEN_STOP                                            ~N  
  84. ~b~IEND                                                    ~N  
  85. .w
  86.  
  87.     If the above program is written and compiled, the preprocessor will make
  88.     all replacements indicated by the various ~b~I#define~N statements!
  89. .WK5,60
  90.   MAGIC!
  91. .WN
  92.  
  93.     The ~b~I#define~N statements are instructions to the ~Ipreprocessor~N.
  94.     We've actually seen such instructions before!
  95.  
  96.     Remember ~b~I#include <stdio.h>~N  ??
  97.  
  98.     THAT was ~Ialso~N an instruction to the preprocessor .. to replace the phrase,
  99.     ~b~I#include <stdio.h>~N by the library of standard input/output routines.
  100.     ( .. which explains why a compiled program is often very much larger than
  101.     the program we write with our favourite text-editor .. it contains the
  102.     ~Ii/o~N library of functions!)
  103. .K16,32
  104.   I  C!
  105. .WNT
  106.     #include <stdio.h>  and   #include <math.h>   
  107. .R5C1
  108.     Since ~IC~N is supposed to be a ~IPORTABLE~N language (write a C program
  109.     on your favourite text-editor and compile if for ANY computer for which
  110.     you have a compiler), the ~Ist~Nan~Id~Nard ~Ii~Nput/~Io~Nutput routines
  111.     are system dependent ... and not, strictly speaking, part of the language!
  112.     Somebody has written the functions in ~Istdio.h~N with a specific computer
  113.     in mind.
  114. .R12C1
  115.     ... which reminds me ... the library of MATH functions (such as ~b~Isin()~N)
  116.     is NOT in ~Istdio.h~N. If you use them, be sure to ~b~I#include <math.h>~N.
  117. .b11-14
  118. .K16,23
  119.   NOW he
  120. .K16,37
  121.  tells me!
  122. .WNT
  123.      even sexier #definitions    
  124. .R5C1
  125.     In the previous example we used:
  126.  
  127. ~b~I#define  PRINT_x               printf("%d",x) ~N
  128.  
  129.     which meant that, to ~Iprint y~N or ~Iprint a~N etc. we would need more 
  130.     #definitions (like PRINT_y and  PRINT_a).
  131.  
  132.     ~IBUT~N, C is very smart. You can include a ~IVARIABLE~N in the
  133.     #definition (within parentheses!), for example:
  134.  
  135. ~b~I#define  PRINT(x)             printf("%d",x) ~N
  136.  
  137.     ... and now use ~b~IPRINT(y)~N or ~b~IPRINT(a)~N etc and the 
  138.     preprocessor would make the substitutions to ~b~Iy~N or ~b~Ia~N.
  139. .K19,60
  140.  NOTE: ()
  141. .WNT
  142.     SUGAR for the kids    
  143. .R5C1
  144. QUESTION:     How to teach programming to kids?
  145.  
  146. ANSWER:       Invent your own kiddie-C!
  147.  
  148.     Let the kids write this          but have the C-compiler get this
  149.                                            
  150. ~b~IBEGIN                         ~N   ~b~Imain()  {                        ~N
  151. ~b~I    LET x=0;                  ~N   ~b~I    int x=0;                     ~N
  152. ~b~I    IF (x LESS 10) DO         ~N   ~b~I    while (x<10) {               ~N
  153. ~b~I        PRINT(x);             ~N   ~b~I    printf(" %d ",x);            ~N
  154. ~b~I        PRINT(SQUARE(x));     ~N   ~b~I    printf(" %d ",x*x);          ~N
  155. ~b~I        NEWLINE;              ~N   ~b~I    printf("\n");                ~N
  156. ~b~I        INCREASE(x);          ~N   ~b~I    x+=1;                        ~N
  157. ~b~I    ENDIF                     ~N   ~b~I    }                            ~N
  158. ~b~ISTOP                          ~N   ~b~I}                                ~N
  159. .W
  160.     ... can you see what ~I#definitions~N are necessary ???
  161. .WN
  162.     These #definitions:
  163. ~b~I#define  BEGIN         main()  {             ~N
  164. ~b~I#define  LET           int                   ~N
  165. ~b~I#define  IF            while                 ~N
  166. ~b~I#define  LESS          <                     ~N
  167. ~b~I#define  DO            {                     ~N
  168. ~b~I#define  PRINT(x)      printf(" %d ",x)      ~N
  169. ~b~I#define  SQUARE(x)     x*x                   ~N
  170. ~b~I#define  NEWLINE       printf("\n")          ~N
  171. ~b~I#define  INCREASE(x)   x+=1                  ~N
  172. ~b~I#define  ENDIF         }                     ~N
  173. ~b~I#define  STOP          }                     ~N
  174.     turn  this                         into this 
  175. ~b~IBEGIN                         ~N   ~b~Imain()  {                        ~N
  176. ~b~I    LET x=0;                  ~N   ~b~I    int x=0;                     ~N
  177. ~b~I    IF (x LESS 10) DO         ~N   ~b~I    while (x<10) {               ~N
  178. ~b~I        PRINT(x);             ~N   ~b~I    printf(" %d ",x);            ~N
  179. ~b~I        PRINT(SQUARE(x));     ~N   ~b~I    printf(" %d ",x*x);          ~N
  180. ~b~I        NEWLINE;              ~N   ~b~I    printf("\n");                ~N
  181. ~b~I        INCREASE(x);          ~N   ~b~I    x+=1;                        ~N
  182. ~b~I    ENDIF                     ~N   ~b~I    }                            ~N
  183. ~b~ISTOP                          ~N   ~b~I}                                ~N
  184. .WN
  185.  
  186.     Of course the kids would have to type in all those !@#$% #definitions!!!
  187.  
  188.     ... or would they ??
  189.  
  190.     We (the master over~IC~Ner) would have all those !@#$% #definitions!!!
  191.     in a separate file (on disk) called ~Isugar.c~N  so the kids would only
  192.     have to begin their program with:    ~b~I#include <sugar.c>~N
  193.  
  194.     The preprocessor would ~b~I#include~N all those  !@#$% #definitions!!!
  195.     at the beginning of every program, then make all the appropriate
  196.     substitutions/replacements ...
  197. .K16,32
  198.  SUGAR!
  199. .WN
  200.  
  201.  
  202.     We have written the #definitions using CAPITALS to replace C-phrases.
  203.  
  204.     That's not necessary, but ADVISABLE! ( then it's obvious which parts of
  205.     your program are HOME-MADE and which are "real C")
  206.  
  207.     Not only do #definitions allow us to write ~IC~N in a personal dialect,
  208.     but they also allow us to quickly change certain C-phrases.
  209. .K16,32
  210.   you C?
  211. .WNT
  212.       notes from the author   
  213. .R4C1
  214.     On the IBM PC (with the "ansi.sys" program installed), I can clear the
  215.     screen by using :    ~b~Iprintf("?[2J");~N   
  216.     
  217.     In place of the question mark, I type an "escape character"
  218.     by holding down the ~IAlt~N key and typing the number ~I27~N on the
  219.     number pad ... and the "left-arrow" appears when I release the Alt key.
  220.     (I can't do it HERE, in this lesson, 'cause it would clear the screen!!)
  221.  
  222.     Now, I begin my programs with a #definition (among others)
  223.  
  224. ~b~I#define   CLEAR     printf("?[2J")~N
  225.  
  226.     then I can use ~b~ICLEAR;~N  wherever I need it, in my program.
  227.  
  228.     Tomorrow, when I buy a sexier C-compiler for the PC (or learn more ~IC~N!) 
  229.     ... one which has all the features included in "ansi.sys" ... including a
  230.     ~b~Iclr_screen()~N function, I replace the above #definition by:
  231.  
  232. ~b~I#define   CLEAR     clr_screen()~N
  233. .WK19,60
  234. thatISnice
  235. .WNT
  236.     typedefinitions    
  237. .R5C1
  238.     You begin your program with ~b~I#define SAM  int~N and it will be
  239.     ~Ipreprocessed~N, and every occurrence of ~b~ISAM~N will be replaced by
  240.      ~b~Iint~N  ...  as in ~b~ISAM x=0;~N which gets passed on to the compiler
  241.     (by the preprocessor) as ~b~Iint x=0;~N
  242.     
  243.     This "replacement" by the preprocessor holds for anything ... not just 
  244.     DATA TYPES ( so ~b~I#define  NewLinePlease  printf("\n")~N allows you to
  245.     use ~b~INewLinePlease;~N in place of ~b~Iprintf("\n");~N ).
  246.  
  247.     BUT, there is a "special" feature for DATA TYPES, called ~b~Itypedef~N.
  248.     Place, at the beginning of your program:
  249.  
  250. ~b~Itypedef  int   INCHES~N            (note the order!)
  251.  
  252.     ... and you may subsequently use, in your program:
  253.  
  254. ~b~IINCHES   x, y, z;~N
  255.  
  256. .w
  257.     and the variables ~b~Ix~N, ~b~Iy~N and ~b~Iz~N will be regarded (by the compiler)
  258.     as ~b~Iint~N variables.
  259. .K16,60
  260. what'sNEW?
  261. .WN
  262.  
  263.     Hmmmm ...
  264.  
  265. ~b~Itypedef  int   INCHES~N            (note the order!)
  266.  
  267.     doesn't seem like it's any different from
  268.  
  269. ~b~I#define  INCHES   int~N            (note the order!)
  270.  
  271.     BUT, remember the curious way we had to refer to an argument, passed to a
  272.     function, which was ~Iitself~N a function?
  273.  
  274. ~b~Ifloat solve(f,x,error)~N
  275. ~b~Ifloat (*f)();         ~N           (note the curiosity!)
  276. ~b~Ifloat x, error;       ~N
  277. ~b~I{                     ~N
  278.  
  279.     Here, the C-phrase ~b~Ifloat (*f)();~N, says that ~b~If~N is a ~Ipointer~N
  280.     to a ~Ifunction~N, and this function returns a ~Ifloat~N.
  281. .WN
  282. ~b~Ifloat solve(f,x,error)   ~N
  283. ~b~Ifloat (*f)();            ~N           (note the curiosity!)
  284. ~b~Ifloat x, error;          ~N
  285. ~b~I{                        ~N
  286.  
  287.     Now, using ~b~Itypedef~N, we may introduce a home-made DATA TYPE called
  288.     ~IPointer to a Function which returns a Float~N.
  289.  
  290. ~b~Itypedef  float   (*PFF)()~N           (note the order!)
  291.  
  292.     Use the above ~b~Itypedef~N (near the beginning of your program) and
  293.     (MAGIC!) the phrase ~b~IPFF~N is interpreted (by the compiler) as meaning a
  294.     ~IPointer to a Function which returns a Float~N.
  295.  
  296.     Use it, in ~b~Isolve()~N,  like so:
  297. .w
  298.  
  299. ~b~Ifloat solve(f,x,error)   ~N
  300. ~b~IPFF  f;                  ~N 
  301. ~b~Ifloat x, error;          ~N
  302. ~b~I{                        ~N
  303. .K19,60
  304. nice eh?
  305. .WN
  306. .R10C1
  307.     Since ~b~Itypedef~N is more than "just a dumb replacement of characters",
  308.     the preprocessor won't touch it ... but passes it along to the compiler!
  309.  
  310.     ... and THAT makes it different from a ~b~I#define~N too!
  311. .b9-14
  312. .WN
  313. ~b~Itypedef  char  *STRING   ~N      
  314.  
  315.     Here STRING is a pointer to a string and you may write ~b~ISTRING x;~N
  316.     meaning that ~b~Ix~N is a pointer to a ~b~Ichar~Nacter string.
  317.  
  318. ~b~Itypedef  int   VECTOR[5] ~N   
  319.  
  320.    Here VECTOR is an array of 5 ~Iint~Ns and you may write
  321.    ~b~IVECTOR x;~N so ~b~Ix~N is an array of 5 integers.
  322.  
  323. ~b~Itypedef  int   INTEGER   ~N   
  324.  
  325.     Here INTEGER is an int (of course!), and you may write ~b~IINTEGER x;~N
  326.     ... and, when you compile your C program for a different computer
  327.     where ~b~Iint~N DATA TYPES are ~I4 bytes long~N (and you were counting on
  328.     their being only ~I2 bytes long~N!) you change this ~Ione~N statement to:
  329.  
  330. ~b~Itypedef  short INTEGER   ~N   meaning a "short" integer.
  331.  
  332.     and all your references to ~b~IINTEGER x;~N and ~b~IINTEGER y;~N etc.
  333.     will be changed!
  334. .WN
  335.  
  336.  
  337.  
  338.  
  339. .T
  340.    That's all folks!   
  341. .K16,32
  342. au revoir!
  343.  
  344.  
  345. .q
  346.  
  347.  
  348.  
  349.  
  350.  
  351. #include <sugar.c>
  352.  
  353.  
  354.